package com.zihan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zihan.constant.ParamsConstant;
import com.zihan.constant.UserConstant;
import com.zihan.context.UserContext;
import com.zihan.domain.dto.ActivityDTO;
import com.zihan.domain.entity.Activity;
import com.zihan.domain.entity.ActivityParticipant;
import com.zihan.domain.entity.User;
import com.zihan.domain.result.PageResult;
import com.zihan.domain.result.Result;
import com.zihan.domain.vo.ActivityParticiPateVO;
import com.zihan.domain.vo.ActivityVO;
import com.zihan.mapper.ActivityMapper;
import com.zihan.service.IActivityParticipantService;
import com.zihan.service.IActivityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zihan.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 学术活动表 服务实现类
 * </p>
 *
 * @author zhangzihan
 * @since 2025-10-17
 */
@Slf4j
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {

    @Resource
    private ActivityMapper activityMapper;
    @Resource
    private IUserService userService;
    @Resource
    private IActivityParticipantService activityParticipantService;

    @Override
    public Result<PageResult> getList(ActivityDTO activityDTO) {
        if (activityDTO == null) {
            return Result.error(ParamsConstant.LACK_PARAMS);
        }
        Page<Activity> activityPage = new Page<>(activityDTO.getPageNo(), activityDTO.getPageSize());
        activityDTO.setCurrentUserId(UserContext.getCurrentId());
        List<ActivityVO> res = activityMapper.getAllList(activityDTO, activityPage);

        PageResult pageResult = new PageResult();
        pageResult.setCurrent(activityPage.getCurrent());
        pageResult.setTotal(activityPage.getTotal());
        pageResult.setRecords(res);
        return Result.success(pageResult);
    }


    /**
     * 获取当前教师用户活动列表
     */
    @Override
    public Result<PageResult> getCurrentTeacherList(ActivityDTO activityDTO) {
        if (activityDTO == null) {
            return Result.error(ParamsConstant.LACK_PARAMS);
        }
        Long currentId = UserContext.getCurrentId();
        activityDTO.setCurrentUserId(currentId);
        Page<Activity> activityPage = new Page<>(activityDTO.getPageNo(), activityDTO.getPageSize());
        List<ActivityVO> res = activityMapper.getList(activityDTO, activityPage);
        PageResult pageResult = new PageResult();
        pageResult.setCurrent(activityPage.getCurrent());
        pageResult.setTotal(activityPage.getTotal());
        pageResult.setRecords(res);
        return Result.success(pageResult);
    }


    /**
     * 添加活动
     * @param activity
     * @return
     */
    @Override
    public Result<String> addActivity(Activity activity) {
        Result<String> stringResult = checkParams(activity);
        if ("200".equals(stringResult.getCode())) {
            return stringResult;
        }
        // 正常添加数据
        Long currentId = UserContext.getCurrentId();
        activity.setCreatorId(currentId);
        activity.setCreateTime(LocalDateTime.now());
        activity.setUpdateTime(LocalDateTime.now());
        save(activity);
        return Result.success("添加成功");
    }





    // 查看活动详情
    @Override
    public Result<ActivityVO> detail(Long id) {
        Activity activity = lambdaQuery().eq(Activity::getId, id).one();
        ActivityVO activityVO = new ActivityVO();
        BeanUtil.copyProperties(activity, activityVO);
        // 查询发布人信息
        User user = userService.lambdaQuery().eq(User::getId, activity.getCreatorId()).one();
        activityVO.setPublishName(user.getUsername());
        activityVO.setPhone(user.getPhone());
        return Result.success(activityVO);
    }

    @Override
    public Result<String> updateActivity(Activity activity) {
        Result<String> stringResult = checkParams(activity);
        if ("200".equals(stringResult.getCode())) {
            return stringResult;
        }
        // 判断活动是否已经开始，开始就不可以
        if (activity.getStartTime().isBefore(LocalDateTime.now())) {
            return Result.error("活动已经开始，不能修改");
        }
        // 正常添加数据
        Long currentId = UserContext.getCurrentId();
        activity.setCreatorId(currentId);
        activity.setUpdateTime(LocalDateTime.now());
        updateById(activity);
        return Result.success("更新成功");
    }


    // 删除活动
    @Override
    public Result<String> deleteActivity(Long id) {
        // 删除活动
        Activity activity = new Activity().setId(id).setDeleted(UserConstant.DELETE_STATUS);
        updateById(activity);
        return Result.success("删除成功");
    }


    // 报名活动
    @Transactional
    @Override
    public Result<String> signUp(Long id) {
        Long currentId = UserContext.getCurrentId();
        Activity activity = lambdaQuery().eq(Activity::getId, id).one();
        if (activity.getStatus() == 2) {
            return Result.error("活动已结束");
        }
        if (activity.getMaxParticipants() != null) {
            if (activity.getMaxParticipants() <= activity.getCurrentParticipants()) {
                return Result.error("活动已满");
            }
        }
        if (activity.getRegistrationDeadline().isBefore(LocalDateTime.now())) {
            return Result.error("报名已截止");
        }
        if (activity.getCreatorId().equals(currentId)) {
            return Result.error("不能报名自己的活动");
        }
        if (lambdaQuery().eq(Activity::getId, id).eq(Activity::getCreatorId, currentId).count() > 0) {
            return Result.error("不能报名自己的活动");
        }
        activity.setCurrentParticipants(activity.getCurrentParticipants() + 1);
        updateById(activity);
        // 插入记录到活动报名表
        ActivityParticipant activitySignUp = new ActivityParticipant();
        activitySignUp.setActivityId(id);
        activitySignUp.setUserId(currentId);
        activitySignUp.setRegistrationTime(LocalDateTime.now());
        activitySignUp.setAttendanceStatus(0);
        activitySignUp.setCreateTime(LocalDateTime.now());
        activitySignUp.setUpdateTime(LocalDateTime.now());
        activitySignUp.setDeleted(0);
        activityParticipantService.save(activitySignUp);
        return Result.success("报名成功");
    }

    @Transactional
    @Override
    public Result<String> cancelSignUp(Long id) {
        Long currentId = UserContext.getCurrentId();
        Activity activity = lambdaQuery().eq(Activity::getId, id).one();
        // 判断活动是否已经开始
        if (activity.getStartTime().isBefore(LocalDateTime.now())) {
            return Result.error("活动已开始，不能取消报名");
        }
        if (activity.getStatus() == 2) {
            return Result.error("活动已结束，不能取消报名");
        }

        // 人数减一 ，关联表删除数据
        activity.setCurrentParticipants(activity.getCurrentParticipants() - 1);
        updateById(activity);

        // 删除参与记录
        boolean remove = activityParticipantService.remove(
                new LambdaQueryWrapper<ActivityParticipant>()
                        .eq(ActivityParticipant::getActivityId, id)
                        .eq(ActivityParticipant::getUserId, currentId));
        log.info("remove:{},{}", id,currentId);
        return Result.success("取消报名成功");
    }
    @Override
    public void exportAnticipate(Long activity, HttpServletResponse response) throws IOException {
        // 1. 设置响应头（导出文件名）
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = null;

        // 获取activityid,查询名称填充，并且查询出列表数据
        Activity a = lambdaQuery().eq(Activity::getId, activity).one();
        String period = a.getTitle();

        List<ActivityParticiPateVO> list =activityMapper.getAllParticipant(activity);
        // 2. 准备 period 占位符数据
        fileName = URLEncoder.encode(period+"_导出", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        Map<String, Object> map = new HashMap<>();
        map.put("period", period);
        // 从 classpath 读取模板
        InputStream templateStream = this.getClass().getClassLoader().getResourceAsStream("activity_anticipate_template.xlsx");
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                .withTemplate(templateStream)
                .build();

        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        // 填充 period
        excelWriter.fill(map, writeSheet);
        // 填充列表数据
        excelWriter.fill(new FillWrapper(list), writeSheet);
        //  finish
        excelWriter.finish();
    }


    @Override
    public Result<PageResult> getStudentList(ActivityDTO activityDTO) {
        if (activityDTO == null) {
            return Result.error(ParamsConstant.LACK_PARAMS);
        }
        Long currentId = UserContext.getCurrentId();
        activityDTO.setCurrentUserId(currentId);
        Page<Activity> activityPage = new Page<>(activityDTO.getPageNo(), activityDTO.getPageSize());
        List<ActivityVO> res = activityMapper.getStudentList(activityDTO, activityPage);
        PageResult pageResult = new PageResult();
        pageResult.setCurrent(activityPage.getCurrent());
        pageResult.setTotal(activityPage.getTotal());
        pageResult.setRecords(res);
        return Result.success(pageResult);
    }



    // 签到
    @Override
    public Result<String> checkIn(Long id) {
        Long currentId = UserContext.getCurrentId();
        // 更新
        ActivityParticipant res = activityParticipantService.lambdaQuery().eq(ActivityParticipant::getActivityId, id)
                .eq(ActivityParticipant::getUserId, currentId).one();
        res.setAttendanceStatus(1);
        res.setAttendanceTime(LocalDateTime.now());
        res.setUpdateTime(LocalDateTime.now());
        activityParticipantService.updateById(res);
        return Result.success("签到成功");
    }

    // 检查活动参数
    public Result<String> checkParams(Activity activity) {
        if (activity == null) {
            return Result.error(ParamsConstant.LACK_PARAMS);
        }
        if (StrUtil.isBlank(activity.getTitle()) ||
                StrUtil.isBlank(activity.getContent())
                || StrUtil.isBlank(activity.getLocation())
                || Objects.isNull(activity.getStartTime())
                || Objects.isNull(activity.getEndTime())
                || Objects.isNull(activity.getRegistrationDeadline())
        ) {
            return Result.error(ParamsConstant.LACK_PARAMS);
        }
        return Result.success("200");
    }
}
